﻿using System;
using System.Text;

/// <summary>
/// 字符流数据解析器
/// </summary>
public class Parser
{
    protected byte[] m_Buffer;
    protected int m_iBufferLen;
    protected byte m_Spiter;
    protected int m_iRPos;

    public const int STRING_MAXLENGTH = 10240;

    public Parser()
    {
        m_Buffer = null;
        m_iBufferLen = 0;
        m_Spiter = 0;
        m_iRPos = 0;
    }

    public Parser(byte[] buffer, int iBufferLen, char spider)
    {
        m_Buffer = buffer;
        m_iBufferLen = iBufferLen;
        m_Spiter = Convert.ToByte(spider);
        m_iRPos = 0;
    }

    //获取当前读指针位置
    public int GetReadPos()
    {
        return m_iRPos;
    }

    // 设置当前读指针位置
    public void SetReadPos(int iPos)
    {
        m_iRPos = iPos;
    }

    // 清除缓冲区数据及读指针位置
    public void Clear()
    {
        m_Buffer = null;
        m_iBufferLen = 0;
        m_iRPos = 0;
    }

    // 重置数据
    public void Reset(byte[] buffer, int iBufferLen, char spiter)
    {
        m_Buffer = buffer;
        m_iBufferLen = iBufferLen;
        m_Spiter = Convert.ToByte(spiter);
        m_iRPos = 0;
    }

    // 设置设置分割字符
    public void SetSpitChar(char spiter)
    {
        m_Spiter = Convert.ToByte(spiter);
    }

    // 跳过一个
    public bool Skip()
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            m_iRPos++;
            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                m_iRPos++;
            }
            m_iRPos++;
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取字节数据
    public bool ReadByte(ref byte ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[16]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 16)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = byte.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取字符数据
    public bool ReadChar(ref char ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[16]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 16)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++; ret = char.Parse(buff.ToString());
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取布尔数据
    public bool ReadBool(ref bool ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[16]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 16)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = bool.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取short数据
    public bool ReadShort(ref short ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[16]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 16)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = short.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取整形数据
    public bool ReadInt(ref int ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[16]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 16)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = int.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取浮点数据
    public bool ReadFloat(ref float ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[32]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 32)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = float.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取long数据
    public bool ReadLong(ref long ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[32]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 32)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = long.Parse(Encoding.UTF8.GetString(buff, 0, pos));
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取短的string数据(utf8格式)
    public bool ReadShortString(ref string ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[32]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < 32)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = Encoding.UTF8.GetString(buff, 0, pos);
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取string数据(utf8格式)
    public bool ReadString(ref string ret)
    {
        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[STRING_MAXLENGTH]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < STRING_MAXLENGTH)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++;
            ret = Encoding.UTF8.GetString(buff, 0, pos);
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }

    // 读取byte数组数据
    public bool ReadString(ref byte[] ret, int iLen)
    {
        // 判断传入参数
        if (ret == null || iLen <= 0)
        {
            return false;
        }

        // 长度越界，则返回false
        if (m_iRPos > m_iBufferLen)
        {
            return false;
        }

        byte[] buff = new byte[STRING_MAXLENGTH]; int pos = 0;
        if (m_Buffer[m_iRPos] != m_Spiter)
        {
            buff[pos] = m_Buffer[m_iRPos];
            pos++; m_iRPos++;

            while ((m_Buffer[m_iRPos] != m_Spiter) && (m_iRPos < m_iBufferLen))
            {
                if (pos < STRING_MAXLENGTH)
                {
                    buff[pos] = m_Buffer[m_iRPos];
                    pos++;
                }
                m_iRPos++;
            }
            m_iRPos++; buff.CopyTo(ret, iLen);
        }
        else
        {
            m_iRPos += 1;
            return false;
        }
        return true;
    }
}